/*
 * table_Expression.c
 *
 *  Created on: 2012-5-14
 *      Author: guanxiaoying
 */

#include "../../parser/coredef.h"
#include "../../parser/cc/cc.h"
#define TableSize  (sizeof(EXPRESSIONINFO))
#define TableType  PEXPRESSIONINFO
#define stTable stExpressionManager.memoryBlocks
#define maxTable  stExpressionManager.maxRecordNum
#define  maxNumPerBlk  (stExpressionManager.astMaxNum_Block)
typedef struct _EXPRESSIONINFO
{
	U4		ulNodeKind;		/* 2 */
	union{
		AST	astDec;
		AST	astValue;
		AST	astConstStr;
		AST   astSymDefInfo;
		AST  astStmt;
		AST astExpList;
	}unTable;							/* 3 */
	AST		astType;				/* 4 */
	AST		astCastType;			/* 5 */
	AST		astValueInfo;			/* 6 */
	AST		astLocation;			/* 7 */
	UCHAR		ucWarningFlg;		/* 8 */
	UCHAR		ucLValueFlg;		/* 9 */
	UCHAR		ucModifiableFlg;	/* 10 */
	SCHAR		cConstFlg;		/* 11 */
	U4		usParentKind;		/* 12 */
	union{
		AST		astStmtInfo;
		AST		astExpInfo;
		AST     astInit;
		AST     astDeclarator;
	}unParent;	/* 13 */
	AST		astChildNode[2];		/* 16 */
} EXPRESSIONINFO, *PEXPRESSIONINFO;

/* get the object */
static TABLEMANAGER stExpressionManager = {
//		U4                  usIdx;
		0,
//		PSZ				    con_pszName;    constant
		__FILE__,
//		U2					con_usSize;		constant
		TableSize,
//		U2					block_num;	　　　　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_Block;     １回設定のみ
		0,
//		S4					astTabNum_LastPage; 　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_LastPage;     Reset clear  際　要
		0,
//		U4					ulMaxByte;	　　　　　　　　　　クリアしない
		0,
//		U4					con_minPageSize;　　　　　　　　　　constant
		0
};
static VOID resetListener( U4  procid, U2 index )
{
	if( procid == stExpressionManager.u4Idx )
	{
		if( index > 0 && index < MAX_VOLUMN_OF_TABLE )
		{
			stTable[ index-1] = NULL;
		}
	}
}
static TableType core_getTable( AST index )
{
	TableType temp = (TableType)Check_Com( &stExpressionManager, resetListener, index );
	if( temp != NULL ){ return &temp[index%maxNumPerBlk]; } return NULL;
}


static BOOL ClearTable( VOID )
{
	return Clear_Com( &stExpressionManager );
}
static BOOL ResetTable( VOID )
{
	return Reset_Com( &stExpressionManager );
}
static BOOL AllocTable( AST astReqArg )
{
	return AllocTable_Com( &stExpressionManager, astReqArg, resetListener );
}
static AST getMaxLineNum( VOID ){
	return maxTable;
}
/* give up the way that defining get/set function pointer in the struct,
 * because of memory volume.
 */
static U4 getNodeKind( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ulNodeKind;
}
static U4 setNodeKind( AST index, U4 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ulNodeKind = value;
}
static AST getResValue( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_CONSTANT ){
		return 0;
	}
	return pTbl->unTable.astValue;
}
static AST setResValue( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_CONSTANT ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_CONSTANT;
	return pTbl->unTable.astValue = value;
}
static AST getResConstStr( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_STRING ){
		return 0;
	}
	return pTbl->unTable.astConstStr;
}
static AST setResConstStr( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_STRING ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_STRING;
	return pTbl->unTable.astConstStr = value;
}
static AST getResDecl( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_DECLARATION ){
		return 0;
	}
	return pTbl->unTable.astDec;
}
static AST setResDecl( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_DECLARATION ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_DECLARATION;
	return pTbl->unTable.astDec = value;
}
static AST getResSymbol( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_IDENTIFIER ){
		return 0;
	}
	return pTbl->unTable.astDec;
}
static AST setResSymbol( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_IDENTIFIER ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_IDENTIFIER;
	return pTbl->unTable.astDec = value;
}
static AST getResToken( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_TOKEN ){
		return 0;
	}
	return pTbl->unTable.astDec;
}
static AST setResToken( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_TOKEN ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_TOKEN;
	return pTbl->unTable.astDec = value;
}
static AST getResStmt( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_STATEMENT ){
		return 0;
	}
	return pTbl->unTable.astStmt;
}
static AST setResStmt( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_STATEMENT ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_STATEMENT;
	return pTbl->unTable.astStmt = value;
}
static AST getInitExpList( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != EXPR_INITEXPRLIST ){
		return 0;
	}
	return pTbl->unTable.astExpList;
}
static AST setInitExpList( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulNodeKind != 0 && pTbl->ulNodeKind != EXPR_INITEXPRLIST ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->ulNodeKind  );
	}
	pTbl->ulNodeKind = EXPR_INITEXPRLIST;
	return pTbl->unTable.astExpList = value;
}
static AST getType( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astType;
}
static AST setType( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astType = value;
}
static AST getCastedType( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astCastType;
}
static AST setCastedType( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astCastType = value;
}
static AST getConstValue( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astValueInfo;
}
static AST setConstValue( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astValueInfo = value;
}
static AST getCodeScp( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astLocation;
}
static AST setCodeScp( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astLocation = value;
}
static BOOL isIllegal( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ucWarningFlg;
}
static BOOL setIllegal( AST index, BOOL value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ucWarningFlg = value;
}
static BOOL isLValue( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ucLValueFlg;
}
static BOOL setLValue( AST index, BOOL value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ucLValueFlg = value;
}
static BOOL isModifiable( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ucModifiableFlg;
}
static BOOL setModifiable( AST index, BOOL value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ucModifiableFlg = value;
}
static S2 getConstFlg( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->cConstFlg;
}
static S2 setConstFlg( AST index, S2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->cConstFlg = value;
}
static U2 getParentKind( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->usParentKind;
}
static U2 setParentKind( AST index, U2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->usParentKind = value;
}
static AST getParent_Stmt( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != KIND_STATEMENTINFO ){
		return 0;
	}
	return pTbl->unParent.astStmtInfo;
}
static AST setParent_Stmt( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != 0 && pTbl->usParentKind != KIND_STATEMENTINFO ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->usParentKind  );
	}
	pTbl->usParentKind = KIND_STATEMENTINFO ;
	return pTbl->unParent.astStmtInfo = value;
}
static AST getParent_Exp( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != KIND_EXPRESSIONINFO ){
		return 0;
	}

	return pTbl->unParent.astExpInfo;
}
static AST setParent_Exp( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != 0 && pTbl->usParentKind != KIND_EXPRESSIONINFO ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->usParentKind  );
	}
	pTbl->usParentKind = KIND_EXPRESSIONINFO ;
	return pTbl->unParent.astExpInfo = value;
}
static AST getParent_ExpList( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != KIND_INITIALEXPLIST ){
		return 0;
	}
	return pTbl->unParent.astInit;
}
static AST setParent_ExpList( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != 0 && pTbl->usParentKind != KIND_INITIALEXPLIST ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->usParentKind  );
	}
	pTbl->usParentKind = KIND_INITIALEXPLIST ;
	return pTbl->unParent.astInit = value;
}
static AST getParent_Designation( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != KIND_INITDESIGNATION ){
		return 0;
	}
	return pTbl->unParent.astInit;
}
static AST setParent_Designation( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != 0 && pTbl->usParentKind != KIND_INITDESIGNATION ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->usParentKind  );
	}
	pTbl->usParentKind = KIND_INITDESIGNATION ;
	return pTbl->unParent.astInit = value;
}
static AST getParent_Declarator( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != KIND_DECLARATOR ){
		return 0;
	}
	return pTbl->unParent.astDeclarator;
}
static AST setParent_Declarator( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->usParentKind != 0 && pTbl->usParentKind != KIND_DECLARATOR ){
		Throw_MemoryError( &stExpressionManager, DATA_SETTING_MISS, index, pTbl->usParentKind  );
	}
	pTbl->usParentKind = KIND_DECLARATOR ;
	return pTbl->unParent.astDeclarator = value;
}
static AST getLeftNode( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astChildNode[0];
}
static AST setLeftNode( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astChildNode[0] = value;
}
static AST getRightNode( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astChildNode[1];
}
static AST setRightNode( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astChildNode[1] = value;
}
const EXPRESSIONACCESS stExpressionAccess = {
		ClearTable,
		ResetTable,
		AllocTable,
		getMaxLineNum,
//		ACCESS_U4_FIELD   opKind;
		{
				getNodeKind,
				setNodeKind
		},
//		ACCESS_IDX_FIELD  result_value;
		{
				getResValue,
				setResValue
		},
		{
				getResConstStr,
				setResConstStr
		},
//		ACCESS_IDX_FIELD  result_declaration;
		{
				getResDecl,
				setResDecl
		},
//		ACCESS_IDX_FIELD  result_symbol;
		{
				getResSymbol,
				setResSymbol
		},
//		ACCESS_IDX_FIELD  result_symbol;
		{
				getResToken,
				setResToken
		},
//		ACCESS_IDX_FIELD  result_statement;
		{
				getResStmt,
				setResStmt
		},
//		ACCESS_IDX_FIELD  result_exprlist;
		{
				getInitExpList,
				setInitExpList
		},
//		ACCESS_IDX_FIELD  type;
		{
				getType,
				setType
		},
//		ACCESS_IDX_FIELD  castedType;
		{
				getCastedType,
				setCastedType
		},
//		ACCESS_IDX_FIELD  constValue;
		{
				getConstValue,
				setConstValue
		},
//		ACCESS_IDX_FIELD  codeScp;
		{
				getCodeScp,
				setCodeScp
		},
//		ACCESS_BOOL_FIELD bIllegal;
		{
				isIllegal,
				setIllegal
		},
//		ACCESS_BOOL_FIELD blValue;
		{
				isLValue,
				setLValue
		},
//		ACCESS_BOOL_FIELD bModifiabe;
		{
				isModifiable,
				setModifiable
		},
//		ACCESS_S2_FIELD  constFlg;
		{
				getConstFlg,
				setConstFlg
		},
//		ACCESS_U2_FIELD  parentKind;
		{
				getParentKind,
				setParentKind
		},
//		ACCESS_IDX_FIELD parent_statement;
		{
				getParent_Stmt,
				setParent_Stmt
		},
//		ACCESS_IDX_FIELD parent_expression;
		{
				getParent_Exp,
				setParent_Exp
		},
//		ACCESS_IDX_FIELD parent_explist;
		{
				getParent_ExpList,
				setParent_ExpList
		},
//		ACCESS_IDX_FIELD parent_declarator;
		{
				getParent_Declarator,
				setParent_Declarator
		},
		{
				getParent_Designation,
				setParent_Designation
		},
//		ACCESS_IDX_FIELD leftChild;
		{
				getLeftNode,
				setLeftNode
		},
//		ACCESS_IDX_FIELD rightChild;
		{
				getRightNode,
				setRightNode
		}
};
